﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace z05_winform
{
    class GridViewHelper
    {
        #region 增操作
        public static void AddColumn(DataGridView dataGridView, string content)
        {
            DataGridViewTextBoxColumn acCode = new DataGridViewTextBoxColumn();
            acCode.Name = content;
            acCode.DataPropertyName = content;
            acCode.HeaderText = content;
            dataGridView.Columns.Add(acCode);
        }


        //添加 很多 列标题
        public static void AddColumns(DataGridView dataGridView, string[] content)
        {
            for (int i = 0; i < content.Length; i++)
            {
               AddColumn(dataGridView, content[i]);
            }
        }
        /// <summary>
        /// 如果你想第一列是一个checkbox的话 就要给startIndex一个默认值1
        /// 你就要先调用AddColumnCheckbox这个方法将多选框添加上
        /// </summary>
        /// <param name="dataGridView"></param>
        /// <param name="content"></param>
        /// <param name="startIndex"></param>
        public static void AddRow(DataGridView dataGridView, string[] content,int startIndex=0)
        {
            AddRow(dataGridView, content,startIndex, Color.Aqua);
        }
        public static void AddRow(DataGridView dataGridView, string[] content,int startIndex, Color backColor)
        {

            try
            {
                dataGridView.EndEdit();   //此处必须加上结束编辑状态代码，切记
                dataGridView.Rows.Add();
                // 寻找无数据的行
                for (int k = 0; k < dataGridView.Rows.Count; k++)
                {
                    // 判断当前行是否为空可以拿来使用
                    if (dataGridView.Rows[k].Cells[startIndex].Value == null || dataGridView.Rows[k].Cells[startIndex].Value == "")
                    {
                        // 将传来的数组数据导入到表里面
                        //for (int i = 0; i < dataGridView.Columns.Count; i++)
                        for (int i = 0; i < content.Length; i++)
                        {
                            dataGridView.Rows[k].Cells[i+ startIndex].Value = content[i];
                        }
                        dataGridView.Rows[k].DefaultCellStyle.BackColor = backColor;

                        return;// 数据全部写完了后就可以不需要进行最外层的循环，直接跳出即可
                    }
                }
            }
            catch (System.IndexOutOfRangeException ex)
            {
                MessageBox.Show("添加行操作出了问题，请重试！" + ex);
            }
            dataGridView.Refresh();
        }

        public static void AddColumnButton(DataGridView dataGridView, string headerTxt, string text)
        {
            //在datagridview中添加button按钮
            DataGridViewButtonColumn btn = new DataGridViewButtonColumn();

            btn.Name = "btn_" + text;
            btn.HeaderText = headerTxt;
            btn.DefaultCellStyle.NullValue = text;
            dataGridView.Columns.Add(btn);

            //删除最后一行的那个按钮
            //dataGridView.Rows[dataGridView.RowCount - 1].Cells[GetColumnsIndex(dataGridView, headerTxt)].Value = "";

        }
        //static DataGridViewCheckBoxColumn columncb = new DataGridViewCheckBoxColumn();
        //添加多选框
        public static void AddColumnCheckbox(DataGridView dataGridView, string headerTxt)
        {
            dataGridView.EndEdit();
            DataGridViewCheckBoxColumn columncb = new DataGridViewCheckBoxColumn();
            {
                columncb.FlatStyle = FlatStyle.Standard;
                columncb.HeaderText = headerTxt;
                columncb.Name = "cb_check";
                columncb.TrueValue = true;
                columncb.FalseValue = false;
                columncb.DataPropertyName = "IsChecked";
                columncb.CellTemplate = new DataGridViewCheckBoxCell();
            }
            //给datagridview加复选框的初始化
            //datagridview的Name为dataList
            dataGridView.Columns.Add(columncb);
        }

        #endregion

        #region 删操作
        /// <summary>
        /// 移除复选框选中的行
        /// </summary>
        /// <param name="dataGridView"></param>
        /// <param name="index"></param>
        public static void RemoveCheckboxSelectedRows(DataGridView dataGridView,int index=0) {
            List<int> list = new List<int>();
            foreach (var item in dataGridView.Rows)
            {
                DataGridViewRow row = item as DataGridViewRow;
                if (row.Cells[index] != null && row.Cells[index].Value != null)
                {
                    if ((bool)row.Cells[index].Value)
                    {
                        list.Add(row.Index);
                    }
                }
            }
            dataGridView.EndEdit();

            for (int i = list.Count - 1; i >= 0; i--)
            {
                dataGridView.Rows.RemoveAt(list[i]);
            }
        }



        /// <summary> 移除所有列
        /// 需要传入表对象
        /// </summary>
        public static void RemoveAllColumns(DataGridView dataGridView)
        {
            while (dataGridView.Columns.Count > 0)
            {
                for (int i = 0; i < dataGridView.Columns.Count; i++)
                {
                    dataGridView.Columns.RemoveAt(i);
                }
            }
        }

        /// <summary> 移除所有列
        /// 需要传入表对象
        /// </summary>
        public static void RemoveRowAtIndex(DataGridView dataGridView, int index)
        {
            if (dataGridView.Rows.Count > 0)
            {
                dataGridView.Rows.RemoveAt(index);
            }
        }

        /// <summary> 移除所有行
        /// 需要传入表对象
        /// </summary>
        public static void RemoveAllRow(DataGridView dataGridView)
        {
            try
            {
                while (dataGridView.Rows.Count > 0)
                {
                    for (int i = 0; i < dataGridView.Rows.Count; i++)
                    {
                        DataGridViewRow row2 = dataGridView.Rows[i];
                        dataGridView.Rows.Remove(row2);// 移除选中的行
                    }
                }
            }
            catch (System.InvalidOperationException ex)
            {
                //MessageBox.Show("操作出了问题，请重试！" + ex);
            }
            dataGridView.Refresh();
        }
        /// <summary>
        /// 清空整个view
        /// </summary>
        /// <param name="dataGridView"></param>
        public static void Clear(DataGridView dataGridView)
        {
            try
            {
                dataGridView.Rows.Clear();
            }
            catch (Exception e)
            {
            }

        }

        /// <summary> 移除指定的烈的表头
        /// 需要传入表对象和指定列里的内容
        /// </summary>
        public static void RemoveColumn(DataGridView dataGridView, String TitleName)
        {
            for (int i = 0; i < dataGridView.Columns.Count; i++)
            {
                if (dataGridView.Columns[i].HeaderText == TitleName)
                {
                    dataGridView.Columns.RemoveAt(i);
                    return;
                }
            }
        }

        #endregion


        #region 查操作
        /// <summary> 获取到数据表里面某一行里面的数据内容
        /// </summary>
        /// <returns>string[] 字符串数组</returns>
        public static string[] GetRowsData(DataGridView dataGridView, int index)
        {
            string[] temp = new string[dataGridView.Columns.Count];// 创建一个字符串素组

            try
            {
                for (int i = 0; i < dataGridView.Columns.Count; i++)
                {
                    temp[i] = (dataGridView.Rows[index].Cells[i].Value == null ? "" : dataGridView.Rows[index].Cells[i].Value.ToString());
                }
                return temp;
            }
            catch (System.ArgumentOutOfRangeException ex)
            {// 索引超出范围
                MessageBox.Show("当前搜索的行在列表中并不存在！");
            }
            return new string[] { "", "" };
        }


        /// <summary> 获取某个值单元格所在某行的索引位置
        /// 数据表对象 - 查询的数据内容
        /// </summary>
        /// <returns>返回int值</returns>
        public static int GetRowsFirstIndex(DataGridView dataGridView, string content)
        {
            for (int i = 0; i < dataGridView.Rows.Count; i++)
            {
                for (int k = 0; k < dataGridView.Columns.Count; k++)
                {
                    if (dataGridView.Rows[i].Cells[k].Value != null && dataGridView.Rows[i].Cells[k].Value.ToString() == content)
                    {
                        return i;
                    }
                }
            }
            return -1;
        }

        /// <summary> 获取某行的索引位置
        /// </summary>
        /// <returns>返回int值</returns>
        public static int GetRowCount(DataGridView dataGridView)
        {

            return dataGridView.RowCount;
        }
        /// <summary> 获取某列的索引位置
        /// </summary>
        /// <returns>返回int值</returns>
        public static int GetColumnsIndex(DataGridView dataGridView, string content)
        {

            for (int k = 0; k < dataGridView.Columns.Count; k++)// 循环列
            {
                if (dataGridView.Columns[k].HeaderText == content)
                {
                    return k;// 返回列索引
                }
            }

            return 0;
        }
        /// <summary>
        /// 返回选中行的下标
        /// </summary>
        /// <param name="dataGridView"></param>
        /// <returns></returns>

        public static int GetSelectedRowIndex(DataGridView dataGridView)
        {

            for (int k = 0; k < dataGridView.Rows.Count; k++)// 循环行
            {
                if (dataGridView.Rows[k].Selected)
                {
                    return k;
                }
            }

            return 0;
        }
        /// <summary> 获取指定的表的所有表标题
        /// </summary>
        /// <param name="dataGridView">指定的表对象</param>
        /// <returns>字符串数组</returns>
        public static string[] GetAllTitle(DataGridView dataGridView)
        {
            string[] tempStr = new string[dataGridView.Columns.Count];
            for (int i = 0; i < dataGridView.Columns.Count; i++)
            {
                tempStr[i] = dataGridView.Columns[i].HeaderText;
            }
            return tempStr;
        }
        #endregion


        #region 改操作
        /// <summary> 修改指定的索引行内的内容
        /// </summary>
        /// <param name="dataGridView">数据表对象</param>
        /// <param name="contont">修改的内容</param>
        /// <param name="index">行索引</param>
        public static void UpdateRowsAtIndex(DataGridView dataGridView, string[] contont, int index)
        {
            for (int i = 0; i < dataGridView.Rows[index].Cells.Count; i++)
            {
                dataGridView.Rows[index].Cells[i].Value = contont[i];
            }
        }
        #endregion

        #region 禁止操作
        /// <summary> 禁止点击了表标题后对内容进行排序
        /// </summary>
        /// <param name="dataGridView">表对象</param>
        public static void BanSort(DataGridView dataGridView)
        {
            for (int i = 0; i < dataGridView.Columns.Count; i++)
            {
                dataGridView.Columns[i].SortMode = DataGridViewColumnSortMode.NotSortable;
            }
        }

        /// <summary> 将表头平均占据整个表的宽度
        /// </summary>
        /// <param name="dataGridView"></param>
        public static void SetTitleAvgWidth(DataGridView dataGridView)
        {
            if (dataGridView.Columns.Count <= 1) { return; }
            int width = dataGridView.Size.Width / dataGridView.Columns.Count;

            for (int i = 0; i < dataGridView.Columns.Count; i++)
            {
                dataGridView.Columns[i].Width = width;
            }
        }

        /// <summary> 开启表控件的双缓冲器
        /// 双缓冲的原理：尽量快的输出图像，使输出在一个刷新周期内完成，
        /// 如果输出内容很多比较慢，那么采用内存缓冲的方法，先把要输出的内容在内存准备好，然后一次性输出到窗体上，
        /// 简单的说来就是在窗口刷新一次的过程中，让所有图元同时显示到窗口中。
        /// </summary>
        /// <param name="dataGridView">表对象</param>
        public static void DataGridViewDoubleBuffered(DataGridView dataGridView)
        {
            Type dgvType = dataGridView.GetType();
            PropertyInfo pi = dgvType.GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic);
            pi.SetValue(dataGridView, true, null);
        }

        public static void SetAlign(DataGridView dataGridView)
        {
            for (int i = 0; i < dataGridView.Rows.Count; i++)
            {
                dataGridView.Rows[i].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
            }
        }

        #endregion
    }
}
